﻿<documents created="2010-12-15 11:35:33Z"><document src="C:\Users\Anders\Documents\automatones\Visual Studio\AutomaTones\AutomaTones\Controller\CAViewController.cs" renderPrefix="s0"><chunk hits="-1" domain="unknown"><source><![CDATA[/*
 * A CaViewController controls the messaging between views and the model. It subscribes to user events from the view and sends updates
 * on the evolvement of a Cellular Automaton. All user interaction with an IVIEW is handled and propogated to the right places. As all interaction
 * and modelling in the sysmtem goes through this class, it also defines the logic behind how the system reacts to system manipulation. Due to the
 * diffrences between the hardware and the gui some seperate logical commands to this class are needed, but in general their behavour is merged
 * together and abstracted in the same way.
 * Author: Anderes Høst | ahkj@itu.dk
 * Date: 04 Dec 2010
 */
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Drawing;
using System.IO;
using AutomaTones.HW_Sense_Compute;
using AutomaTones.Model.Automaton_Model;
using AutomaTones.Model.Automaton_Model.RuleLib;
using AutomaTones.Model.MIDI;
using AutomaTones.Model.MIDI.Mappers;
using AutomaTones.Model.Tools;
using AutomaTones.View;
using AutomaTones.View.Midi_Out_View;
using Microsoft.Pex.Framework;
using Midi;


namespace AutomaTones.Controller {
    [PexClass]
    partial class CAViewController : IController<IView> {

        private const int LAUNCHPAD_DIMENSION = 8;
        private const int NUMBER_OF_STATES = 7;
        private Channel _chosenChannel;
        private IHardwareView _hardWareView;
        private State[,] _grid, _rule;
        private List<State[,]> rules;
        private bool _userIsSettingCAInitialState, _userIsSettingCARule, _stateBeingChanged, _caReadyForReplay;

        //Cell manipulation
        private State _state = new State();
        private int _x, _y, validTimestamp;

        //Musical references 
        private MidiOut _mo;
        private Tempo _tempo;
        private IMapper _mapper = new BechTranslator(); // we need this for insitialization
        private ConnectVirtualMidi _vm;

        private CellularAutomaton _ca;
        private List<CellularAutomaton> _caHistory;

        public CAViewController() {
            rules = new List<State[,]>();
            _grid = new State[LAUNCHPAD_DIMENSION, LAUNCHPAD_DIMENSION];
            //for custom rule setting dimension are never biiger than 3 x 3
            _rule = new State[3, 3];
            try {
                _vm = new ConnectVirtualMidi();
            } catch (Exception ex) {
                //Midi not installed correctly and en exception is unavoidable. 
                //As graphical interaction is still possible we don't kill the system but let the user
                //continue to use it in a less functional way way. If critcal one could consider
                //the state of CaViewController invalid and exit here.
                Console.WriteLine(ex.Message);
            }
              _mo = new MidiOut(Channel.Channel1, _mapper);
              _tempo = MainController.Tempo;

            _caHistory = new List<CellularAutomaton>();
            ResetRuleGrid();
            ResetGrid();
        }

        public bool IsPLaying { get; set; }
        public bool IsPaused { get; set; }
        public int Volume { get; set; }
        public List<Channel> Channels { get; set; }

        /// <summary>
        /// Add an IView to this controller.
        /// </summary>
        /// <param name="view"></param>
        [PexMethod]
        public void AddView(IView view) {
            Contract.Requires(view != null);
            Contract.Ensures(View == view);
            View = view;
        }

        /// <summary>
        /// Add an IHardwareView to this controller. If the inputmode is set to launchpad in the controller this
        /// view will be notified.
        /// </summary>
        /// <param name="hardWareView"></param>
        [PexMethod]
        public void AddHwView(IHardwareView hardWareView) {
            Contract.Requires(hardWareView != null);
            Contract.Ensures(_hardWareView == hardWareView);
            _hardWareView = hardWareView;
        }

        /// <summary>
        /// This method should be invoked when a pad is pressed on the launchpad. 
        /// </summary>
        [PexMethod]
        public void LaunchpadClicked(int x, int y) {
            if (!OkToUseLaunchpad()) return;
            CellClicked(x, y);
        }

        /// <summary>
        /// Called whenever one of the statechange buttons on the right side of the Launchpad is pressed or released
        /// </summary>
        /// <param name="pushingStateButton">Indicates if a statechange button is being pressed</param>
        [PexMethod]
        public void StateButtonDown(bool pushingStateButton) {
            _stateBeingChanged = pushingStateButton;
        }

        /// <summary>
        /// Updates the state after a statechange button has been released
        /// </summary>
        /// <param name="state">The state change selected on the Launchpad</param>
        [PexMethod]
        public void State(State state) {
            Contract.Requires(state != null);
            _state = state;
        }

        /// <summary>
        /// Method that reacts to an'Ok' sent from the implementer of IView. It reacts in response to
        /// what the user was doing - setting up a rule or CA.
        /// </summary>
        [PexMethod]
        public void Ok() {
            if (_userIsSettingCAInitialState && (ChosenCAType == CAType.TwoDimensional ||
                                                 ChosenCAType == CAType.TwoDimensionalEXT || 
                                                 ChosenCAType == CAType.OneDimensional)) {
                //was setting initial state and is now done
                _userIsSettingCARule = true; //Now setting the rule
                _userIsSettingCAInitialState = false;
                ResetRuleGrid();
                if (_hardWareView != null)
                    _hardWareView.ClearGrid();
                View.SystemMessage("Set rule # " + (rules.Count + 1) +
                                   " Press ok to enter more rules. Press Play to listen.");
            } else if (_userIsSettingCARule) {
                SaveRule();
                ResetRuleGrid();
            }
        }

        /// <summary>
        /// Play was sent from the user. Doesn't actually 'play music' but sets up the process of generating music
        /// based on CAs by gathering the input and choices of the user.
        /// </summary>
        [PexMethod]
        public void PlaySentFromUser() {
            if (_caReadyForReplay) {
                IsPLaying = true;
                return;
            }
            if (ChosenCAType == CAType.GameOfLife) {
                CaTypeSetup.SetupGameOfLife(ref _ca, _grid.GetLength(0), _grid.GetLength(1), 2, _grid);
            } else if (ChosenCAType == CAType.GameOfLifeEXT) {
                CaTypeSetup.SetupGameOfLife(ref _ca, _grid.GetLength(0), _grid.GetLength(1), NUMBER_OF_STATES, _grid);
            } else if (ChosenCAType == CAType.OneDimensional) {
                //    SetUpOneDimensionalCA();
            } else if (ChosenCAType == CAType.TwoDimensional) {
                SaveRule();
                _userIsSettingCARule = false;
                CaTypeSetup.SetupTwoDimensional(ref _ca, rules, 2, (uint)_grid.GetLength(0), _grid);
                ResetGrid();
            } else if (ChosenCAType == CAType.TwoDimensionalEXT) {
                SaveRule();
                _userIsSettingCARule = false;
                CaTypeSetup.SetupTwoDimensional(ref _ca, rules, 8, (uint)_grid.GetLength(0), _grid);
                ResetGrid();
            }


            _userIsSettingCARule = false;
            IsPaused = false;
            if (_ca != null)
            {
                IsPLaying = true;
                View.SystemMessage("Play");
            }
        }

        [PexMethod]
        public void Evolve() {
            if (TimeStamp == _caHistory.Count) { //we're not 'back in time'
                _caHistory.Add((CellularAutomaton)_ca.Clone());
                _ca.Evolve();
            }
        }

        /// <summary>
        /// Make this CaViewController play it's Cellular Automaton. This includes updating registred views
        /// and sound.
        /// </summary>
        [PexMethod] 
        public void Play() {
            //make sure we have a valid timestamp, could go wrong when going forward in time
            validTimestamp = TimeStamp;
            if (validTimestamp >= _caHistory.Count)
                return;
            State[,] grid = Convertor.CAToStateGrid(_caHistory[validTimestamp]);
            if (MainController.LaunchpadConnected && InputMode == InputMode.Launchpad)
                _hardWareView.SetGrid(grid);
            _mo.SetGrid(grid);
            View.SetGrid(grid);
            TimeStamp++;
        }

        /// <summary>
        /// Pause was clicked. Clicking pause twice works as a kind of reset of the CA and views.
        /// </summary>
        [PexMethod]         
        public void Pause() {
            if (IsPLaying) {
                IsPLaying = false;
                _caReadyForReplay = true;
            } else if (IsPaused) { //if pause is clicked twice
                IsPLaying = false;
                ResetGrid();
                _caHistory.Clear();
                TimeStamp = 0;
                validTimestamp = 0;
                _caReadyForReplay = false;
                if (_hardWareView != null)
                    _hardWareView.ClearGrid();
                View.SystemMessage("CA has been reset");
            }
            IsPaused = true;
            View.SystemMessage("Pause");
        }

        //Go forward in time!
        [PexMethod]
        public void Forward() {
            if (TimeStamp == _caHistory.Count) {
                Evolve();
                Play();
            } else TimeStamp++;
        }

        //rewind
        [PexMethod]
        public void Rewind() {
            if (0 <= TimeStamp - 3)
                TimeStamp -= 3;
            if (IsPaused && _caReadyForReplay) {
                State[,] grid = Convertor.CAToStateGrid(_caHistory[TimeStamp]);
                if (MainController.LaunchpadConnected && InputMode == InputMode.Launchpad)
                    _hardWareView.SetGrid(grid);
                _mo.SetGrid(grid);
                View.SetGrid(grid);
            }
        }


        /// <summary>
        /// Save the current instance of of the ca along relevant history and state for later replication.
        /// </summary>
        /// <param name="name"></param>
        [PexMethod]         
        public void Save(String name) {
            Contract.Requires(name != null);
            if (_ca == null) {
                View.SystemMessage("No CA to save.");
                return;
            }
            CaSaveContainer cas = new CaSaveContainer() {
                CellularAutomaton = _ca,
                CaHistory = _caHistory,
                ChosenChannel = _chosenChannel,
                Volume = this.Volume,
                Grid = new Size() { Width = _grid.GetLength(0), Height = _grid.GetLength(1) }
            };
            SaveCa.Save(cas, name);
            View.SystemMessage("Cellular Automaton saved as " + name);
        }

        /// <summary>
        /// Load and and play the automaton that is found
        /// </summary>
        /// <param name="path"></param>
        [PexMethod]
        public void Load(String path) {
            Contract.Requires(path.Length > 0);
            if (File.Exists(path)) {
                CaSaveContainer csc = LoadCA.Load(path);
                if (csc == null) {
                    View.SystemMessage("CA at: " + path + " not found");
                    return;
                }
                this._ca = csc.CellularAutomaton;
                this._caHistory = csc.CaHistory;
                this.Volume = csc.Volume;
                this._chosenChannel = csc.ChosenChannel;
                this._grid = new State[csc.Grid.Width, csc.Grid.Height];
                ResetGrid();
                _userIsSettingCARule = false;
                _userIsSettingCAInitialState = false;
                InputMode = InputMode.Off;

                View.DisplayChannel(this._chosenChannel);
                View.SetVolume(Volume);
                IsPLaying = true;
            }
        }

        [PexMethod]
        public void SetVolume(int volume) {
            Contract.Ensures(0 <= Volume && Volume <= 100);
            if (0 <= volume && volume <= 100)
                this.Volume = volume;
            _mo.SetVolume(volume);
        }

        /// <summary>
        /// Sets the channel that is chosen for sound output.
        /// </summary>
        [PexMethod] 
        public void SetChannel(Channel c) {
            Contract.Ensures(_chosenChannel.Equals(c));
            _chosenChannel = c;
            _mo.SetChannel(c);
        }

        /// <summary>
        /// Updates a grid. The controller always knows what cell there's being tampered with.
        /// </summary>
        /// <param name="grid">The grid that needs to be updated</param>
        [PexMethod]        
        private void SetGridCell(State[,] grid) ]]></source>
</chunk>
<method name="SetGridCell" namespace="AutomaTones.Controller" type="AutomaTones.Controller.CAViewController" typeName="CAViewController" token="60000fc" module="AutomaTones.exe"><hits><hit index="0" value="1"/>
<hit index="1" value="1"/>
<hit index="17" value="1"/>
<hit index="18" value="1"/>
<hit index="19" value="1"/>
<hit index="20" value="1"/>
<hit index="21" value="1"/>
<hit index="22" value="1"/>
<hit index="23" value="1"/>
<hit index="24" value="1"/>
<hit index="25" value="1"/>
<hit index="26" value="1"/>
<hit index="27" value="1"/>
<hit index="28" value="1"/>
<hit index="29" value="1"/>
<hit index="30" value="2"/>
<hit index="31" value="1"/>
<hit index="32" value="1"/>
<hit index="33" value="1"/>
<hit index="34" value="2"/>
<hit index="35" value="1"/>
<hit index="36" value="1"/>
<hit index="37" value="1"/>
<hit index="38" value="1"/>
<hit index="39" value="1"/>
<hit index="40" value="2"/>
<hit index="41" value="1"/>
<hit index="42" value="1"/>
<hit index="43" value="1"/>
<hit index="44" value="1"/>
<hit index="71" value="1"/>
<hit index="72" value="1"/>
<hit index="73" value="1"/>
<hit index="74" value="1"/>
<hit index="75" value="1"/>
<hit index="76" value="1"/>
<hit index="77" value="1"/>
<hit index="78" value="1"/>
<hit index="79" value="1"/>
<hit index="80" value="1"/>
<hit index="93" value="1"/>
<hit index="95" value="1"/>
<hit index="96" value="1"/>
<hit index="97" value="1"/>
</hits>
<coverage domain="userortestcode" unit="block" covered="9" total="18" coveredRatio="0.5"/>
</method>
<chunk hits="1" offset="0000" domain="userortestcode"><source><![CDATA[{]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
            Contract.Requires(grid != null);
            ]]></source>
</chunk>
<chunk hits="1" offset="0001" domain="userortestcode"><source><![CDATA[if (_stateBeingChanged)]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[ ]]></source>
</chunk>
<chunk hits="0" offset="000e" domain="userortestcode"><source><![CDATA[{]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
                ]]></source>
</chunk>
<chunk hits="0" offset="000f" domain="userortestcode"><source><![CDATA[grid[_x, _y].CurrentState = _state.CurrentState;]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
            ]]></source>
</chunk>
<chunk hits="0" offset="0032" domain="userortestcode"><source><![CDATA[}]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[ else ]]></source>
</chunk>
<chunk hits="1" offset="0035" domain="userortestcode"><source><![CDATA[{]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
                ]]></source>
</chunk>
<chunk hits="1" offset="0036" domain="userortestcode"><source><![CDATA[grid[_x, _y].CurrentState = ++grid[_x, _y].CurrentState % NUMBER_OF_STATES;]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
            ]]></source>
</chunk>
<chunk hits="3" offset="0073" domain="userortestcode"><source><![CDATA[}]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
            ]]></source>
</chunk>
<chunk hits="3" offset="0074" domain="userortestcode"><source><![CDATA[if (IsPLaying || (_caReadyForReplay))]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
                ]]></source>
</chunk>
<chunk hits="0" offset="008c" domain="userortestcode"><source><![CDATA[_ca[_x, _y] = grid[_x, _y].CurrentState;]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
            ]]></source>
</chunk>
<chunk hits="1" offset="00c9" domain="userortestcode"><source><![CDATA[View.SetCell(_x, _y, grid[_x, _y]);]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
            ]]></source>
</chunk>
<chunk hits="0" offset="00f3" domain="userortestcode"><source><![CDATA[NotifyLaunchpadOnCellClick(_x, _y, grid[_x, _y]);]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
        ]]></source>
</chunk>
<chunk hits="0" offset="0118" domain="userortestcode"><source><![CDATA[}]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[

        /// <summary>
        /// A cell was clicked. 
        /// </summary>
        /// <param name="xPos"></param>
        /// <param name="yPos"></param>
        [PexMethod]        
        private void CellClicked(int xPos, int yPos) ]]></source>
</chunk>
<method name="CellClicked" namespace="AutomaTones.Controller" type="AutomaTones.Controller.CAViewController" typeName="CAViewController" token="60000fd" module="AutomaTones.exe"><hits><hit index="0" value="1"/>
<hit index="1" value="1"/>
<hit index="6" value="1"/>
<hit index="7" value="1"/>
<hit index="8" value="1"/>
<hit index="9" value="1"/>
<hit index="10" value="1"/>
<hit index="21" value="1"/>
<hit index="22" value="1"/>
<hit index="23" value="1"/>
<hit index="24" value="1"/>
<hit index="25" value="1"/>
<hit index="26" value="1"/>
<hit index="27" value="1"/>
<hit index="28" value="1"/>
<hit index="29" value="1"/>
<hit index="30" value="1"/>
<hit index="31" value="1"/>
<hit index="33" value="1"/>
<hit index="34" value="1"/>
<hit index="35" value="1"/>
<hit index="37" value="1"/>
<hit index="38" value="1"/>
<hit index="39" value="1"/>
<hit index="40" value="1"/>
<hit index="41" value="1"/>
<hit index="42" value="1"/>
</hits>
<coverage domain="userortestcode" unit="block" covered="11" total="19" coveredRatio="0.57894736842105265"/>
</method>
<chunk hits="1" offset="0000" domain="userortestcode"><source><![CDATA[{]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
            Contract.Requires(_grid != null);
            Contract.Requires(_rule != null);
            Contract.Requires(0 <= _x && 0 <= _y);
            //Only affect cells if user is in a set cell kind of mode that is also valid.);););
            ]]></source>
</chunk>
<chunk hits="1" offset="0001" domain="userortestcode"><source><![CDATA[if (_userIsSettingCARule && !CellIsValid(xPos, yPos))]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
                ]]></source>
</chunk>
<chunk hits="0" offset="0018" domain="userortestcode"><source><![CDATA[return;]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
            ]]></source>
</chunk>
<chunk hits="1" offset="001d" domain="userortestcode"><source><![CDATA[_x = xPos;]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
            ]]></source>
</chunk>
<chunk hits="2" offset="0024" domain="userortestcode"><source><![CDATA[_y = yPos;]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
            ]]></source>
</chunk>
<chunk hits="2" offset="002b" domain="userortestcode"><source><![CDATA[if (_userIsSettingCARule && xPos < _rule.GetLength(0) && yPos < _rule.GetLength(1))]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
                ]]></source>
</chunk>
<chunk hits="0" offset="005b" domain="userortestcode"><source><![CDATA[SetGridCell(_rule);]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
            else ]]></source>
</chunk>
<chunk hits="1" offset="006a" domain="userortestcode"><source><![CDATA[if ((xPos < _grid.GetLength(0) && yPos < _grid.GetLength(1)) && CellIsValid(xPos, yPos))]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
                ]]></source>
</chunk>
<chunk hits="1" offset="009a" domain="userortestcode"><source><![CDATA[SetGridCell(_grid);]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
        ]]></source>
</chunk>
<chunk hits="1" offset="00a7" domain="userortestcode"><source><![CDATA[}]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[

        /// <summary>
        /// Checks if it is ok to use the Launchpad as input
        /// </summary>
        /// <returns></returns>
        private bool OkToUseLaunchpad() {
            return (_userIsSettingCAInitialState || _userIsSettingCARule) && InputMode == InputMode.Launchpad;
        }

        private void NotifyLaunchpadOnCellClick(int x, int y, State state) {
            if (InputMode == InputMode.Launchpad && _hardWareView != null) {
                _hardWareView.SetCell(x, y, state);
            }
        }

        private void SaveRule() {
            rules.Add(_rule);
            View.SystemMessage("Set rule # " + (rules.Count + 1) + " Press ok to enter more rules. Press Play to listen.");
        }

        /// <summary>
        /// Check to see if a clicked cell is valid according to the rule selected. At this point the user has a grid of 3 x 3
        /// </summary>
        /// <returns></returns>
        private Boolean CellIsValid(int xPos, int yPos) ]]></source>
</chunk>
<method name="CellIsValid" namespace="AutomaTones.Controller" type="AutomaTones.Controller.CAViewController" typeName="CAViewController" token="6000101" module="AutomaTones.exe"><hits><hit index="0" value="1"/>
<hit index="1" value="1"/>
<hit index="6" value="1"/>
<hit index="14" value="1"/>
<hit index="15" value="1"/>
<hit index="19" value="1"/>
<hit index="20" value="1"/>
<hit index="21" value="1"/>
<hit index="23" value="1"/>
<hit index="24" value="1"/>
</hits>
<coverage domain="userortestcode" unit="block" covered="7" total="19" coveredRatio="0.36842105263157893"/>
</method>
<chunk hits="1" offset="0000" domain="userortestcode"><source><![CDATA[{]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
            ]]></source>
</chunk>
<chunk hits="1" offset="0001" domain="userortestcode"><source><![CDATA[if (_userIsSettingCAInitialState && ChosenCAType == CAType.OneDimensional)]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
                ]]></source>
</chunk>
<chunk hits="0" offset="001c" domain="userortestcode"><source><![CDATA[return yPos == 0;]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
            ]]></source>
</chunk>
<chunk hits="1" offset="0023" domain="userortestcode"><source><![CDATA[if (_userIsSettingCARule && (xPos >= _rule.GetLength(0) || yPos >= _rule.GetLength(0)))]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
                ]]></source>
</chunk>
<chunk hits="0" offset="0053" domain="userortestcode"><source><![CDATA[return false;]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
            ]]></source>
</chunk>
<chunk hits="1" offset="0057" domain="userortestcode"><source><![CDATA[if (ChosenCAType == CAType.OneDimensional)]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
                ]]></source>
</chunk>
<chunk hits="0" offset="0067" domain="userortestcode"><source><![CDATA[return yPos == 0 || (yPos == 1 && xPos == 1);]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
            ]]></source>
</chunk>
<chunk hits="1" offset="007b" domain="userortestcode"><source><![CDATA[return true;]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
        ]]></source>
</chunk>
<chunk hits="1" offset="007f" domain="userortestcode"><source><![CDATA[}]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[

        /// <summary>
        /// Change the CAType.
        /// </summary>
        /// <param name="type"></param>
        private void ChangeCaType(CAType type) {
            //Dimension changed, and we don't combine these so clear the listed rules in this case and go to config of ca
            if (type != ChosenCAType && type == CAType.TwoDimensional || type == CAType.OneDimensional) {
                rules.Clear();
                View.SystemMessage("Dimensions can't be combined...");
                _userIsSettingCARule = false;
                _userIsSettingCAInitialState = true;
                this.ChosenCAType = type;
                ResetGrid();
                return;
            }
            this.ChosenCAType = type;
            View.SystemMessage("" + type);
            if (_userIsSettingCARule)
                ResetRuleGrid();
        }

        /// <summary>
        /// Called when a new input mode is selected. For the Launchpad we start using the 8 x 8
        /// already held in this class. For mouse configuration of CA we use the preferred grid used
        /// by the IVIEW
        /// </summary>
        /// <param name="im"></param>
        private void ChangeInputMode(InputMode im) {
            if (IsPLaying) {
                View.SystemMessage("Stop music to modify CA input mode");
                return;
            }
            InputMode = im;
            View.SystemMessage("Input mode: " + this.InputMode);
            switch (im) {
                case InputMode.Launchpad: {
                        _grid = new State[LAUNCHPAD_DIMENSION, LAUNCHPAD_DIMENSION];
                        _userIsSettingCAInitialState = true;
                    }
                    break;
                case InputMode.Mouse: {
                        _grid = View.CustomGrid;
                        _userIsSettingCAInitialState = true;
                    }
                    break;
                case InputMode.Off: {
                        _userIsSettingCAInitialState = false;
                    }
                    break;
            }
            _userIsSettingCARule = false;
            ResetGrid();
            if (rules.Count > 0)
                rules.Clear();
        }

        /// <summary>
        /// Changes the mapper
        /// </summary>
        /// <param name="mapper"></param>
        private void ChangeMapper(Mapper mapper) {
            switch (mapper) {
                case Mapper.BechTranslator: {
                        _mo.SetMapper(new BechTranslator());
                        View.SystemMessage("" + mapper);
                    }
                    break;
                case Mapper.HqstTranslator: {
                        _mo.SetMapper(new HqstTranslator());
                         View.SystemMessage("" + mapper);
                    }
                    break;
                case Mapper.MozartTranslator:
                    {
                        _mo.SetMapper(new MozartTranslator());
                    }
                    break;
                case Mapper.SampleTranslator:
                    {
                        _mo.SetMapper(new SampleTranslator());
                    }
                    break;
                default: _mo.SetMapper(new BechTranslator());
                    break;
            }
        }

        /// <summary>
        /// Adds a pattern to the Cellular Automaton
        /// </summary>
        /// <param name="column"></param>
        /// <param name="row"></param>
        private void ApplyCaPattern(GameOfLife.GofPattern pattern, int column, int row) {
            if (this.InputMode == InputMode.Off)
                return;
            if (_ca == null) {
                if (ChosenCAType == CAType.GameOfLife) {
                    CaTypeSetup.SetupGameOfLife(ref _ca, _grid.GetLength(0), _grid.GetLength(1), 1, _grid);
                } else if (ChosenCAType == CAType.GameOfLifeEXT)
                    CaTypeSetup.SetupGameOfLife(ref _ca, _grid.GetLength(0), _grid.GetLength(1), NUMBER_OF_STATES, _grid);
                ChangeCaType(CAType.Off);
            }
            GameOfLife.AddGofPattern(_ca, pattern, column, row);
            IsPLaying = true;
            View.SystemMessage("Playing. " + pattern);
        }


        /// <summary>
        /// Reset the launchpad sized grid on the IView and the IHardWareView. If the ca type and config is one dimensional
        /// it add some state to the cells that are not clickable.
        /// </summary>
        public void ResetGrid() {
            for (int i = 0; i < _grid.GetLength(0); i++) {
                for (int j = 0; j < _grid.GetLength(1); j++) {
                    if (ChosenCAType == CAType.OneDimensional && !CellIsValid(i, j))
                    {
                        _grid[i, j] = new State(0, 8, 0);
                        continue;
                    }
                    _grid[i, j] = new State();
                }
            }
            if (_hardWareView != null)
                _hardWareView.ClearGrid();
            if (View != null) {
                View.SetGridDimension(_grid.GetLength(0), _grid.GetLength(1));
                View.SetGrid(_grid);
            }
        }

        /// <summary>
        /// Reset the rule grid on the IView and the IHardWareView. If the rule is one dimensional
        /// it add some state to the cells that are not clickable.
        /// </summary>
        private void ResetRuleGrid() {
            for (int i = 0; i < _rule.GetLength(0); i++)
                for (int j = 0; j < _rule.GetLength(1); j++) {
                    if (ChosenCAType == CAType.OneDimensional && !CellIsValid(i, j)) {
                        _rule[i, j] = new State(0, 8, 0);
                        continue;
                    }
                    _rule[i, j] = new State();
                }
            if (_hardWareView != null) {
                _hardWareView.ClearGrid();
                _hardWareView.SetGrid(_rule);
            }
            if (View != null) {
                View.SetGridDimension(_rule.GetLength(0), _rule.GetLength(1));
                View.SetGrid(_rule);
            }
        }

        private int TimeStamp { get; set; }
        private IView View { get; set; }
        private CAType ChosenCAType { get; set; }
        private InputMode InputMode { get; set; }

        /// <summary>
        /// Trivial.
        /// Setup this controller with the view that has just registred itself to
        /// this controller. It assigns methods to delegates and eventhandlers. 
        /// </summary>
        public void SetUp() {
            View.OnCellClickEvent += CellClicked;
            View.OnPlayButtonClickEvent += PlaySentFromUser;
            View.OnPauseButtonClickEvent += Pause;
            View.OnVolumeChangeEvent += SetVolume;
            View.OnChannelChangeEvent += SetChannel;
            View.OnOkButtonClickEvent += Ok;
            View.OnSaveButtonClickEvent += Save;
            View.OnLoadButtonClickEvent += Load;
            View.OnInputModeChangeEvent += ChangeInputMode;
            View.OnCATypeChangeEvent += ChangeCaType;
            View.OnMapperChangeEvent += ChangeMapper;
            View.OnRewindButtonClickEvent += Rewind;
            View.OnForwardButtonClickEvent += Forward;
            View.OnApplyCaPatternEvent += ApplyCaPattern;
            //Aval data
            View.Patterns = Model.Utils.AutomatoneTypes.GetPatterns();
            View.DisplayInputModes(Model.Utils.AutomatoneTypes.GetInputModes());
            View.DisplayCATypes(Model.Utils.AutomatoneTypes.GetCaTypes());
            View.DisplayMappers(Model.Utils.AutomatoneTypes.GetMappers());
            View.DisplayChannels(Channels);
        }

        [ContractInvariantMethod]
        private void Invariant() {
            Contract.Invariant(validTimestamp <= _caHistory.Count);
            Contract.Invariant(0 <= this.Volume && this.Volume <= 100);
            //if chosen CA type changes, no old rules should be kept.
            Contract.Invariant(Contract.OldValue(ChosenCAType) != ChosenCAType && rules.Count == 0 && _userIsSettingCARule);
            Contract.Invariant((_rule != null));
            Contract.Invariant(_grid != null);
            Contract.Invariant(rules != null);
            Contract.Invariant(InputMode == InputMode.Launchpad && _hardWareView != null);
            Contract.Invariant(0 <= TimeStamp);
            Contract.Invariant(_caReadyForReplay && _ca != null);
            Contract.Invariant(IsPLaying && _ca != null);
        }
    }
}
]]></source>
</chunk>
</document>
<document src="C:\Users\Anders\Documents\automatones\Visual Studio\AutomaTones\AutomaTones\Model\Automaton Model\State.cs" renderPrefix="s1"><chunk hits="-1" domain="unknown"><source><![CDATA[using System;
using System.Diagnostics.Contracts;

namespace AutomaTones.Model.Automaton_Model {
    /// <author>Anders Øland / anoe@itu.dk</author>
    /// <summary>
    /// The state of a cell represented by a discrete value within a given state space.. 
    /// NOTE: Ideally this would be implemented using generics so states could also be decimals.
    /// NOTE: But due to C#'s lack of type constraint options on value types - this was omitted.
    /// </summary>
    [Serializable]
    public class State {
        /// <summary>
        /// The lower boundary of the state space.
        /// </summary>
        public int SpaceMin { get; protected set; }

        /// <summary>
        /// The upper boundary of the state space.
        /// </summary>
        public int SpaceMax { get; protected set; }

        private int _currentState;

        /// <summary>
        /// Current state.
        /// </summary>
        public int CurrentState {
            get ]]></source>
</chunk>
<method name="get_CurrentState" namespace="AutomaTones.Model.Automaton_Model" type="AutomaTones.Model.Automaton_Model.State" typeName="State" token="60001ce" module="AutomaTones.exe"><hits><hit index="0" value="1"/>
<hit index="1" value="1"/>
</hits>
<coverage domain="userortestcode" unit="block" covered="1" total="1" coveredRatio="1"/>
</method>
<chunk hits="1" offset="0000" domain="userortestcode"><source><![CDATA[{]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[ ]]></source>
</chunk>
<chunk hits="1" offset="0001" domain="userortestcode"><source><![CDATA[return _currentState;]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[ ]]></source>
</chunk>
<chunk hits="1" offset="000a" domain="userortestcode"><source><![CDATA[}]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
            protected internal set ]]></source>
</chunk>
<method name="set_CurrentState" namespace="AutomaTones.Model.Automaton_Model" type="AutomaTones.Model.Automaton_Model.State" typeName="State" token="60001cf" module="AutomaTones.exe"><hits><hit index="0" value="2"/>
<hit index="1" value="2"/>
<hit index="2" value="2"/>
</hits>
<coverage domain="userortestcode" unit="block" covered="1" total="1" coveredRatio="1"/>
</method>
<chunk hits="2" offset="0000" domain="userortestcode"><source><![CDATA[{]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
                Contract.Ensures(CurrentState == value);
                ]]></source>
</chunk>
<chunk hits="2" offset="0001" domain="userortestcode"><source><![CDATA[_currentState = value;]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
            ]]></source>
</chunk>
<chunk hits="4" offset="0008" domain="userortestcode"><source><![CDATA[}]]></source>
</chunk>
<chunk hits="-1" domain="unknown"><source><![CDATA[
        }

        private int _nextState;

        /// <summary>
        /// Next state.
        /// </summary>
        public int NextState {
            get { return _nextState; }
            protected internal set {
                Contract.Ensures(NextState == value);
                _nextState = value;
            }
        }

        /// <summary>
        /// Construct a new State. 
        /// </summary>
        /// <param name="spaceMin"></param>
        /// <param name="spaceMax"></param>
        /// <param name="currentState"></param>
        public State(int spaceMin = 0, int spaceMax = 1, int currentState = 0) {
            SpaceMin = spaceMin;
            SpaceMax = spaceMax;
            _currentState = currentState;
        }

        [ContractInvariantMethod]
        private void ObjInvariant() {
            Contract.Invariant(SpaceMin < SpaceMax);
            Contract.Invariant(SpaceMin <= _currentState && SpaceMax >= _currentState);
            Contract.Invariant(SpaceMin <= _nextState && SpaceMax >= _nextState);
        }
    }
}]]></source>
</chunk>
</document>
<document src="(no sources available for some parts of AutomaTones)" missing="true"><method name="get_ChosenCAType" type="AutomaTones.Controller.CAViewController" token="600010c" module="AutomaTones.exe"><hits/>
<coverage domain="userortestcode" unit="block" covered="1" total="1" coveredRatio="1"/>
</method>
<method name="get_IsPLaying" type="AutomaTones.Controller.CAViewController" token="60000e4" module="AutomaTones.exe"><hits/>
<coverage domain="userortestcode" unit="block" covered="1" total="1" coveredRatio="1"/>
</method>
<method name="get_View" type="AutomaTones.Controller.CAViewController" token="600010a" module="AutomaTones.exe"><hits/>
<coverage domain="userortestcode" unit="block" covered="1" total="1" coveredRatio="1"/>
</method>
</document>
</documents>
